package com.autumn.platform.web;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;

import com.autumn.platform.core.context.reqeust.IRequest;
import com.autumn.platform.core.context.reqeust.RequestContextHolder;
import com.autumn.platform.core.context.user.ISessionUser;
import com.autumn.platform.core.spring.SpringHolder;
import com.autumn.platform.web.request.IWebRequest;

public class WebHolder {

    /**
     * 用户存储在会话中的属性名称
     */
    private static final String USER_IN_SESSION_ATTR_NAME = WebHolder.class.getName() + ".USER_IN_SESSION_ATTR_NAME";

    /**
     * Web应用
     */
    private static ServletContext application;// 应用级别
    /**
     * 项目根
     */
    private static String projectRoot = null;// 应用级别

    /**
     * 项目路径
     */
    private static String projectPath = null;// 应用级别

    /**
     * 设置应用对象
     * 
     * @param application Web应用对象，整个Web应用唯一
     */
    public static void setApplication(final ServletContext application) {
        if (WebHolder.application != application) {
            WebHolder.application = application;
        }
    }

    /**
     * 获取应用对象
     * 
     * @return Web应用对象
     */
    public static ServletContext getApplication() {
        return application;
    }

    /**
     * 获取项目路径
     * 
     * @return 项目路径
     */
    public static String getProjectPath() {
        if (null == projectPath) {
            synchronized (WebHolder.class) {
                if (null == projectPath) {
                    String realPath = getApplication().getRealPath("/");
                    if (realPath.charAt(realPath.length() - 1) != '/' && realPath.charAt(realPath.length() - 1) != '\\') {
                        realPath = realPath + "/";
                    }
                    projectPath = realPath;
                }
            }
        }
        return projectPath;
    }

    /**
     * 获取项目根
     * 
     * @return 项目根
     */
    public static String getProjectRoot() {
        if (null == projectRoot) {
            synchronized (WebHolder.class) {
                if (null == projectRoot) {
                    projectRoot = getApplication().getContextPath();
                }
            }
        }
        return projectRoot;
    }

    /**
     * 获取当前线程的请求信息
     * 
     * @return
     * @throws IllegalStateException
     */
    public static IWebRequest getWebRequest() {
        IRequest request = RequestContextHolder.getRequest();
        if (request instanceof IWebRequest) {
            return (IWebRequest) request;
        }
        return null;
    }

    public static NativeWebRequest getNativeWebRequest() {
        return getWebRequest().getNativeWebRequest();
    }

    /**
     * 获取当前线程的请求
     * 
     * @return
     */
    public static HttpServletRequest getRequest() {
        return getNativeWebRequest().getNativeRequest(HttpServletRequest.class);
    }

    /**
     * 获取当前线程的响应
     * 
     * @return
     */
    public static HttpServletResponse getResponse() {
        return getNativeWebRequest().getNativeResponse(HttpServletResponse.class);
    }

    /**
     * 获取当前线程的请求属性
     * 
     * @param key
     * @return
     */
    public static Object getRequestAttribute(String key) {
        return getNativeWebRequest().getAttribute(key, RequestAttributes.SCOPE_REQUEST);
    }

    /**
     * 获取当前线程的请求属性
     * 
     * @param key
     * @param cls
     * @return
     */
    public static <T> T getRequestAttribute(String key, Class<T> cls) {
        Object rs = getRequestAttribute(key);
        return SpringHolder.convert(rs, cls);
    }

    /**
     * 设置当前线程的请求属性
     * 
     * @param key
     * @param value
     */
    public static void setRequestAttribute(String key, Object value) {
        getNativeWebRequest().setAttribute(key, value, RequestAttributes.SCOPE_REQUEST);
    }

    /**
     * 移除当前线程的请求属性
     * 
     * @param key
     */
    public static void removeRequestAttribute(String key) {
        getNativeWebRequest().removeAttribute(key, RequestAttributes.SCOPE_REQUEST);
    }

    /**
     * 获取当前会话ID
     * 
     * @return
     */
    public static String getSessionId() {
        return getWebRequest().getSessionId();
    }

    /**
     * 获取当前会话属性
     * 
     * @param key
     * @return
     */
    public static Object getSessionAttribute(String key) {
        return getNativeWebRequest().getAttribute(key, RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 获取当前会话属性
     * 
     * @param key
     * @param cls
     * @return
     */
    public static <T> T getSessionAttribute(String key, Class<T> cls) {
        Object rs = getSessionAttribute(key);
        return SpringHolder.convert(rs, cls);
    }

    /**
     * 设置当前会话属性
     * 
     * @param key
     * @param value
     */
    public static void setSessionAttribute(String key, Object value) {
        getNativeWebRequest().setAttribute(key, value, RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 移除当前会话属性
     * 
     * @param key
     */
    public static void removeSessionAttribute(String key) {
        getNativeWebRequest().removeAttribute(key, RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 移除并返回当前会话属性
     * 
     * @param key
     * @param cls
     */
    public static <T> T getAndRemoveSessionAttribute(String key, Class<T> cls) {
        NativeWebRequest nativeWebRequest = getNativeWebRequest();
        Object value = nativeWebRequest.getAttribute(key, RequestAttributes.SCOPE_SESSION);
        if (null != value) {
            nativeWebRequest.removeAttribute(key, RequestAttributes.SCOPE_SESSION);
            return SpringHolder.convert(value, cls);
        }
        return null;
    }

    /**
     * 获取会话中的用户
     * 
     * @return
     */
    public static ISessionUser getSessionUser() {
        return getSessionAttribute(USER_IN_SESSION_ATTR_NAME, ISessionUser.class);
    }

    /**
     * 获取会话中的用户
     * 
     * @return
     */
    public static <U extends ISessionUser> U getSessionUser(Class<U> cls) {
        return getSessionAttribute(USER_IN_SESSION_ATTR_NAME, cls);
    }

    /**
     * 保持用户至会话
     * 
     * @param sessionUser
     */
    public static void saveSessionUser(ISessionUser sessionUser) {
        setSessionAttribute(USER_IN_SESSION_ATTR_NAME, sessionUser);
    }

    /**
     * 移除用户从会话
     * 
     * @param sessionUser
     */
    public static void removeSessionUser() {
        removeSessionAttribute(USER_IN_SESSION_ATTR_NAME);
    }
}
